#!/bin/bash

#------------------------------------------------------------------------------
# Alternative to the 'man' command, meant to automatically reflow the manual
# pages on terminal resize.
#
# TODO:
# 	- Options should be implemented via an env var to avoid slowing the code
# 	- Implement caching
# 		Caching should store previously rendered output for specific terminal
# 		widths. This would allow to skip some recompilations.
# 	- Check if less has the --save-marks option
# 	- Restore previous position in manual
# 	- Print menu for man pages when no arguments are passed?
# 	- Flag to exit on file not found
# 	- Flag to allow for LESSOPEN
#-----------------------------------------------------------------------------

usage() {
	cat <<-USAGE
		Usage: automan [PAGES]

		Wrapper for man that automatically reflows text on terminal resize.
	USAGE
	return $1
}

declare -r base_dir='/tmp/autoless'
declare -a pages_arr
declare -a less_args=(-L)

[[ $1 == '--restore' ]] && less_args+=(+\'\') && shift

mkdir $base_dir 2>/dev/null

# WARNING: be careful when moving this line as COLUMNS is only set after an
# external command is called
columns=$COLUMNS

# Cleaunp
trap "rm -rf $base_dir" EXIT

# Treat arguments as potential pages
for page in "$@" ; do
	# Find the path to the page and format its name
	page=$(man -w $page)
	(($? != 0)) && continue # Skip missing pages
	page_base=$(basename $page)
	page_path=$base_dir/${page_base/bz2/txt}
	pages_arr+=($page_path)
	
	# Prepare man pages to be output
	# The '-rLL' and '-rLT' make the output fit to terminal window
	bzcat $page |\
	groff -spte -mandoc -Tutf8 -rLL=$((COLUMNS-1))n -rLT=$((COLUMNS-1))n \
	>${page_path} 2>/dev/null
done

# Pass the formated pages path to a less job
less ${less_args[@]} "${pages_arr[@]}" &

# Sends SIGTERM to 'less' and restarts this script to force a redraw
trap '
	(:;:) # pseudo-command used to force bash to set COLUMNS
	if (($columns != $COLUMNS)) ; then
		kill $!
		exec $(basename $0) --restore $@
	fi
' WINCH

# Alternative to 'wait' (which was causing weird issues).
# Keep running while the 'less' process is alive.
while ps -o pid= $! >/dev/null ; do : ; done
